#pragma once

#include "Reflection/Property.h"
#include "File/JsonUtils.h"
#include "Object/Object.h"
#include "Reflection/PropertyList.h"
#include "ObjectPtrSerializer.h"
#include "BinarySerializer.h"

class WHENGINE_API CJsonSerializer
{
public:
    CJsonSerializer(
        std::shared_ptr<IObjectSerializer> InObjectSerializer=std::make_shared<CObjectPtrPathSerializer>()
        ,std::shared_ptr<CBinarySerializer> InBinarySerializer=nullptr
    )
    :ObjectSerializer(InObjectSerializer)
    ,BinarySerializer(InBinarySerializer)
    {}

    std::shared_ptr<CJsonNodeBase> SerializeToJson(const void* InFieldPtr, CProperty* InProperty);


    std::shared_ptr<CJsonNodeBase> SerializeToJson(const void* InValuePtr,CType * InType,bool bIsBinaryValue=false);

    std::shared_ptr<CJsonNodeBase> SerializeToJson(RObjectPtr InObject);


protected:
    std::shared_ptr<IObjectSerializer> ObjectSerializer;

    //BinarySerializer is used to serialize binary data
    //if BinarySerializer is nullptr, will serialize data to json
    std::shared_ptr<CBinarySerializer> BinarySerializer;
};


class WHENGINE_API CJsonDeserializer
{
public:    
    CJsonDeserializer(
        std::shared_ptr<IObjectDeserializer> InObjectSerializer=std::make_shared<CObjectPtrPathSerializer>()
        ,std::shared_ptr<CBinaryDeserializer> InBinaryDeserializer=nullptr
    )
    :ObjectSerializer(InObjectSerializer)
    ,BinaryDeserializer(InBinaryDeserializer)
    {}

    void DeserializeFromJson(RObjectPtr InObject,std::shared_ptr<CJsonNodeBase> InJson);


    void DeserializeFromJson(void* InFieldPtr, CProperty* InProperty,std::shared_ptr<CJsonNodeBase> InJson);

    
    void DeserializeFromJson(void* InValuePtr, CType* InType,std::shared_ptr<CJsonNodeBase> InJson,bool bIsBinaryValue=false);

protected:
    std::shared_ptr<IObjectDeserializer> ObjectSerializer;
    std::shared_ptr<CBinaryDeserializer> BinaryDeserializer;

};
